﻿using System;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
using Lk.Common.Timing;
using MT.Common;
using MT.Common.Helper;
using MT.Common.Log;
using MT.WebApi.Core.Filters;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Primitives;
using Microsoft.IdentityModel.Tokens;

namespace MT.WebApi.Core.Auth.OverWrite
{
    public class JwtHelper
    {

        public static string SecretKey { get; set; } = "sdfsdfsrty45634kkhllghtdgdfss345t678fs";
      
        public static string IssueJwt(TokenModelJwt tokenModel)
        {
            var dateTime = DateTime.Now;
            var claims = new Claim[]
            {
              new Claim(JwtRegisteredClaimNames.Jti,tokenModel.UserId.ToString()),
              new Claim("Role",tokenModel.Role),
              new Claim("Phone",tokenModel.Phone),
              new Claim("ClientTypeDic",tokenModel.ClientTypeDic),
              new Claim("Name",tokenModel.Name),
              new Claim("UserId",tokenModel.UserId.ToString()),
              new Claim(JwtRegisteredClaimNames.Iat,dateTime.ToString(),ClaimValueTypes.Integer64),
                    new Claim(JwtRegisteredClaimNames.Exp, tokenModel.ExpireTime.ToString())
            };

            var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(SecretKey));

            var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);

            var jwt = new JwtSecurityToken(issuer: "ym", claims: claims, expires: tokenModel.ExpireTime, signingCredentials: creds);
            var jwtHandler = new JwtSecurityTokenHandler();
            var encodeJwt = jwtHandler.WriteToken(jwt);
            return encodeJwt;

        }
      
        public async Task<string> RefreshAsync(string token, TokenModelJwt dto)
        {
            //var jwtOld = GetExistenceToken(token);
            //if (jwtOld == null)
            //{
            //    return new JwtAuthorizationDto()
            //    {
            //        Token = "未获取到当前 Token 信息",
            //        Success = false
            //    };
            //}

            var jwt = IssueJwt(dto);

            ////停用修改前的 Token 信息
            //await DeactivateCurrentAsync();

            return jwt;
        }

        /// <summary>
        /// 解析
        /// </summary>
        public static TokenModelJwt SerializeJwt(string jwtStr)
        {
            var jwtHandler = new JwtSecurityTokenHandler();
            var jwtToken = jwtHandler.ReadJwtToken(jwtStr);
            object role = new object(); ;
            try
            {
                jwtToken.Payload.TryGetValue("Role", out role);
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                throw;
            }
            var tm = new TokenModelJwt
            {
                UserId = int.Parse(jwtToken.Id),
                Role = role.ToString(),
                ClientTypeDic = jwtToken.Claims.FirstOrDefault(s => s.Type == "ClientTypeDic")?.Value,
                ExpireTime = DateTimeHelper.FromTimestamp(jwtToken.Claims.FirstOrDefault(s => s.Type == "exp").Value.ObjToLong()),
                Name = jwtToken.Claims.FirstOrDefault(s => s.Type == "Name")?.Value,
                Phone = jwtToken.Claims.FirstOrDefault(s => s.Type == "Phone")?.Value
            };
          
            return tm;
        }

        /// <summary>
        /// 获取 HTTP 请求的 Token 值
        /// </summary>
        /// <returns></returns>
        private string GetCurrentAsync()
        {
            var authorizationHeader = MvcContext.GetContext()
                .Request.Headers["authorization"];

            return authorizationHeader == StringValues.Empty
                ? string.Empty
                : authorizationHeader.Single().Split(" ").Last();// bearer tokenvalue
        }
    }

    public class TokenModelJwt
    {

        public int UserId { get; set; }
        public string Role { get; set; }
        public string Name { get; set; }
        public string Phone { get; set; }
        public string ClientTypeDic { get; set; }
        public DateTime ExpireTime { get; set; }

    }
}
